﻿using System.Linq.Expressions;

namespace Ma.Bussiness.MaperExtend;


/// <summary>
/// 生成表达式目录树 泛型缓存 和硬编码同一个层级的,是相对字典映射实体、反射映射实体、序列化反序列化映射实体最快的
/// </summary>
/// <typeparam name="Tin"></typeparam>
/// <typeparam name="Tout"></typeparam>
public static class ExpressionGenericMapper<Tin,Tout>
{
    public static Func<Tin, Tout> _FUNC = null;

    static ExpressionGenericMapper()
    {
        ParameterExpression parameterExpression = Expression.Parameter(typeof(Tin), "p");
        List<MemberBinding> memberBindings = new List<MemberBinding>();
        foreach (var item in typeof(Tout).GetType().GetProperties())
        {
            MemberExpression property = Expression.Property(parameterExpression, typeof(Tin).GetProperty(item.Name));
            MemberBinding memberBinding =Expression.Bind(item, property);
            memberBindings.Add(memberBinding);
        }
        foreach (var item in typeof(Tout).GetType().GetFields())
        {
            MemberExpression property=Expression.Field(parameterExpression,typeof(Tin).GetField(item.Name));
            MemberBinding memberBinding=Expression.Bind(item, property);
            memberBindings.Add(memberBinding);
        }
        MemberInitExpression memberInitExpression =Expression.MemberInit(Expression.New(typeof(Tout)),memberBindings.ToArray());
        Expression<Func<Tin,Tout>> lambda = Expression.Lambda<Func<Tin,Tout>>(memberInitExpression, parameterExpression);
        _FUNC= lambda.Compile();
    }
    public static Tout Maper(Tin Tin)
    {
        return _FUNC(Tin);
    }

}
